import 'dart:isolate';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

/// gengling@huami.com
///
class IsolateMethod extends StatelessWidget {
  final aValueNotifer = ValueNotifier<String>(null);
  final bValueNotifer = ValueNotifier<String>(null);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: [
          ButtonBar(
            alignment: MainAxisAlignment.center,
            children: [
              ValueListenableBuilder(
                  valueListenable: aValueNotifer,
                  builder: (context, String value, child) {
                    return Card(
                      child: Container(
                        width: 500,
                        padding: EdgeInsets.all(20),
                        child: Text(value ?? 'nothing'),
                      ),
                      color: value == null
                          ? Colors.lightGreenAccent
                          : Colors.deepOrangeAccent,
                    );
                  }),
              RaisedButton(
                child: const Text('Create Isolate A with Spawn'),
                elevation: 8.0,
                onPressed: () {
                  createIsolateWithSpawn();
                },
              ),
              ValueListenableBuilder(
                  valueListenable: bValueNotifer,
                  builder: (context, String value, child) {
                    return Card(
                      child: Container(
                        width: 500,
                        padding: EdgeInsets.all(20),
                        child: Text(value ?? 'nothing'),
                      ),
                      color: value == null
                          ? Colors.deepOrangeAccent
                          : Colors.lightGreenAccent,
                    );
                  }),
              RaisedButton(
                child: const Text('Creat Isolate B with Compute'),
                elevation: 8.0,
                onPressed: () {
                  createIsolateWithCompute();
                },
              ),
//              RaisedButton(
//                child: const Text('Creat Isolate B with Spawnuri'),
//                elevation: 8.0,
//                onPressed: () {
//                  createIsolateWithSpawnuri();
//                },
//              ),
            ],
          ),
        ],
      ),
    );
  }

  Future<void> createIsolateWithSpawn() async {
    /// Root Isolate receive port
    final receivePort = ReceivePort();

    /// Root Isolate send port
    final sendPort = receivePort.sendPort;
    sendPort.send('message from root isolate');
    receivePort.listen(
      (dynamic message) {
        if (message[0] == 0) {
          aValueNotifer.value = 'receive Isolate A send port';
          final aSendPort = message[1] as SendPort;
          aSendPort.send('root isolate message');
        } else if (message[0] == 1) {
          aValueNotifer.value = '收到Isolate A的消息>>> $message';
          print('收到Isolate A的消息>>> $message');
        } else {
          aValueNotifer.value = '收到Isolate A的另外一条消息>>> $message';
          print('收到Isolate A的另外一条消息>>> $message');
        }
      },
    );

    /// create new isolate
    final _isolateA = await Isolate.spawn(isolateA, receivePort.sendPort);
  }

  Future<void> createIsolateWithCompute() async {
    final count = await compute(countEven, 100);
    bValueNotifer.value = '收到来自comput的计算结果>>>>$count';
    print('收到来自comput的计算结果>>>>$count');
  }

  /// there is something wrong on flutter
  /// 1.20.not support yet with AOT
  Future<void> createIsolateWithSpawnuri() async {
    final rp = ReceivePort();
    final rootPort = rp.sendPort;

    await Isolate.spawnUri(Uri.base.resolve('./spawnuri.dart'), ['hello, isolate', 'this is args'], rootPort);

    SendPort port;
    rp.listen((dynamic message) {
      print('main isolate message: $message');
      if (message[0] == 0) {
        port = message[1] as SendPort;
      } else {
        port?.send([1, '这条信息是 main isolate 发送的']);
      }
    });
  }
}

///必须是顶级函数或静态函数
void isolateA(SendPort callerSendPort) {
  ///Isolate a的接受端口
  final receivePort = ReceivePort();

  ///获取isolate a的发送端口并把该port发送给root isolate
  final sendPort = receivePort.sendPort;
  callerSendPort.send([0, sendPort]);

  receivePort.listen((dynamic message) {
    print('receive message from root isolate>> $message');
    callerSendPort
        .send([3, 'Isolate A receive message from root isolate, OVER!!!']);
  });
  callerSendPort.send([1, 'Data AA from Isolate A']);
}

/// 必须是顶级函数或静态函数
/// Compute 实现计算偶数的个数
int countEven(int num) {
  print('num is >> $num');
  var count = 0;
  while (num > 0) {
    if (num % 2 == 0) {
      count++;
    }
    num--;
  }
  return count;
}
